﻿using HalconDotNet;

namespace HVision
{
    public abstract class HMetrologyShape : HShape
    {
        internal int iconWidth = 6;

        internal int iconHeight = 18;

        internal bool distOrNum = false;

        internal HMetrologyModel hMetrology = null;

        internal HXLDCont hXLDCont = null;

        internal HXLDCont hContour = null;

        internal HObject hCross = null;

        /// <summary>
        /// 是否显示Cross
        /// </summary>
        public bool DispPoints { get; set; }

        /// <summary>
        /// 是否显示所有卡尺xld
        /// </summary>
        public bool DispPaths { get; set; }

        private double caliperWidth = 5.0;
        /// <summary>
        /// 卡尺宽度(半宽,与测量线相切)
        /// </summary>
        public double CaliperWidth
        {
            get { return caliperWidth; }
            set
            {
                if (value < 1)
                {
                    value = 1;
                }
                caliperWidth = value;
            }
        }

        private double caliperHeight = 20.0;
        /// <summary>
        /// 卡尺高度（半高,与测量线正交）
        /// </summary>
        public double CaliperHeight
        {
            get { return caliperHeight; }
            set
            {
                if (value < 1)
                {
                    value = 1;
                }
                caliperHeight = value;
            }
        }

        private int caliperNum = 20;
        /// <summary>
        /// 卡尺数量
        /// </summary>
        public int CaliperNum
        {
            get { return caliperNum; }
            set
            {
                distOrNum = true;
                caliperNum = value;
            }
        }

        private int measureDistance = 5;
        /// <summary>
        /// 卡尺间距
        /// </summary>
        public int MeasureDistance
        {
            get { return measureDistance; }
            set
            {
                distOrNum = false;
                measureDistance = value;
            }
        }

        private HTransitionType measureTransition = HTransitionType.Bw;
        /// <summary>
        /// 明暗转变
        /// </summary>
        public HTransitionType MeasureTransition
        {
            get { return measureTransition; }
            set { measureTransition = value; }
        }

        private HMetrologySelection measureSelect = HMetrologySelection.first;
        /// <summary>
        /// Selection of end points
        /// "第一个"、“最后一个”、“所有”
        /// </summary>
        public HMetrologySelection MeasureSelect
        {
            get { return measureSelect; }
            set { measureSelect = value; }
        }

        private HMetrologyInterpolation measureInterpolation = HMetrologyInterpolation.nearest_neighbor;
        /// <summary>
        /// 插值类型
        /// </summary>
        public HMetrologyInterpolation MeasureInterpolation
        {
            get { return measureInterpolation; }
            set { measureInterpolation = value; }
        }

        private double measureSigma = 1;
        /// <summary>
        /// Sigma of the Gaussian function for the smoothing
        /// Suggested values: 0.4, 0.6, 0.8, 1.0, 1.5, 2.0, 3.0, 4.0, 5.0, 7.0, 10.0
        /// </summary>
        public double MeasureSigma
        {
            get { return measureSigma; }
            set
            {
                if (value > 100)
                {
                    value = 100;
                }
                if (value < 0.4)
                {
                    value = 0.4;
                }
                measureSigma = value;
            }
        }

        private int measureThreshold = 30;
        /// <summary>
        /// Minimum edge amplitude
        /// Suggested values: 5.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 90.0, 110.0
        /// </summary>
        public int MeasureThreshold
        {
            get { return measureThreshold; }
            set
            {
                if (value > 255)
                {
                    value = 255;
                }
                if (value < 1)
                {
                    value = 1;
                }
                measureThreshold = value;
            }
        }

        private double minScore = 0.7;
        /// <summary>
        /// 最小得分
        /// </summary>
        public double MinScore
        {
            get { return minScore; }
            set
            {
                if (value > 1)
                {
                    value = 1;
                }
                if (value < 0)
                {
                    value = 0.1;
                }
                minScore = value;
            }
        }

        private int numInstances = 1;
        /// <summary>
        /// 成功拟合直线的最大数量（且大于最小得分）
        /// </summary>
        public int NumInstances
        {
            get { return numInstances; }
            set { numInstances = value; }
        }

        private double distanceThreshold = 3.5;
        /// <summary>
        /// 点到拟合直线的距离阈值
        /// List of values: 0, 1.0, 2.0, 3.5, 5.0
        /// </summary>
        public double DistanceThreshold
        {
            get { return distanceThreshold; }
            set { distanceThreshold = value; }
        }

        private int maxNumIterations = -1;
        /// <summary>
        /// RANSAC算法拟合所需迭代次数最大值，
        /// Setting this parameter can be helpful, if the quality of the fitting is not as important as observing time limits. 
        /// However, if "max_num_iterations" is set too low, the algorithm will return low-quality or no results.
        /// </summary>
        public int MaxNumIterations
        {
            get { return maxNumIterations; }
            set { maxNumIterations = value; }
        }

        private int randSeed = 42;
        /// <summary>
        /// RANSAC算法的随机数种子，若设置为0，则随机数生成器以当前时间初始化，测量结果不可复现.
        /// </summary>
        public int RandSeed
        {
            get { return randSeed; }
            set { randSeed = value; }
        }

        private bool instancesOutsideMeasureRegions = false;
        /// <summary>
        /// 超出测量区域的测试是否被存储
        /// </summary>
        public bool InstancesOutsideMeasureRegions
        {
            get { return instancesOutsideMeasureRegions; }
            set { instancesOutsideMeasureRegions = value; }
        }

        /// <summary>
        /// 测量结果[row1,col1,row2,col2]
        /// </summary>
        public HTuple ResultMeasured { get; internal set; }

        /// <summary>
        /// 卡尺测量出所有点坐标Row
        /// </summary>
        public HTuple PointsMeasuredRows;

        /// <summary>
        /// 卡尺测量出所有点坐标Col
        /// </summary>
        public HTuple PointsMeasuredCols;

        /// <summary>
        /// 测量
        /// </summary>
        /// <param name="image"></param>
        public abstract void Measure(HImage image);

    }
}
